package org.zxp.thread.lock;

import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;

/**
 * @program: zxp-thread-test
 * @description:  自己实现的可重入锁
 * @author: X-Pacific zhang
 * @create: 2019-05-12 11:51
 **/
public class MyLock implements Lock {
    private volatile boolean isLock = false;
    private Thread cThread = null;
    private volatile int lockTime = 0;

    @Override
    public synchronized void lock() {
        if(isLock && Thread.currentThread() != cThread){
            try {
                wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        lockTime++;
        isLock = true;
        cThread = Thread.currentThread();
    }

    @Override
    public synchronized void unlock() {
        if(Thread.currentThread() != cThread){
            return;
        }
        lockTime--;
        notify();
        if(lockTime == 0)
            isLock = false;
    }

    static MyLock myLock = new MyLock();
    public static void main(String[] args){
        //测试锁
//        new Thread(myLock::ma).start();
//        new Thread(myLock::mb).start();
        //测试可重入
        myLock.mc();

    }

    public void ma(){
        myLock.lock();
        System.out.println("aaaaaa");
        try {
            Thread.sleep(2000L);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        myLock.unlock();
    }
    public void mb(){
        myLock.lock();
        System.out.println("bbbbbb");
        try {
            Thread.sleep(2000L);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        myLock.unlock();
    }

    public void mc(){
        myLock.lock();
        System.out.println("cccccc");
        md();
        myLock.unlock();
    }

    public void md(){
        myLock.lock();
        System.out.println("dddddd");
        myLock.unlock();
    }


    @Override
    public void lockInterruptibly() throws InterruptedException {

    }

    @Override
    public boolean tryLock() {
        return false;
    }

    @Override
    public boolean tryLock(long time, TimeUnit unit) throws InterruptedException {
        return false;
    }



    @Override
    public Condition newCondition() {
        return null;
    }
}
